package cn.edu.sjtu.permission;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import cn.edu.sjtu.DedexerPlus;

public class APIPermissionChecker extends PermissionChecker {

	DedexerPlus dp;
	
	public APIPermissionChecker(String path) {
		super(path);
	}
	
	public void analyse(HashSet<String> pset, String func, String[] regValue) {
		String f = null;
		if (regValue != null) {	//reflection
			f = regValue[0].split(":")[1];
			if (DedexerPlus.isInvokeCompleted) {
				if (dp != null) {
					LinkedList<String> list = null;
					if (dp.invokeMap.containsKey(func)) {
						list = (LinkedList<String>) dp.invokeMap.get(func);
					} else {
						list = new LinkedList<String>();
					}
					list.add(f);
					dp.invokeMap.put(func, list);
					
					if (dp.reInvokeMap.containsKey(f)) {
						list = (LinkedList<String>) dp.reInvokeMap.get(f);
					} else {
						list = new LinkedList<String>();
					}
					list.add(func);
					dp.reInvokeMap.put(f, list);
				}
			}
		} else {
			f = func;
		}
		if (pMap.containsKey(f)) {
			String p = pMap.get(f);
			if (!p.equals("none")) {
				setPermissionSet(pset, p);
				System.out.println("App require permission: " + f + " " + p);
			}
		}
		int li = f.lastIndexOf(".");
		if (li != -1) {
			String className = f.substring(0, li);
			String methodName = f.substring(li);
			if (DedexerPlus.extendMap.containsKey(className)) {
				className = DedexerPlus.extendMap.get(className).toString();
				String newFunc = className + methodName;
				
				while (pMap.containsKey(newFunc)) {	// check father class
					String p = pMap.get(newFunc);
					if (!p.equals("none")) {
						setPermissionSet(pset, p);
						System.out.println("App require permission: " + newFunc + " " + p);
					}
					if (DedexerPlus.extendMap.get(className) != null) {
					className = DedexerPlus.extendMap.get(className).toString();
					newFunc = className + methodName;
					} else {
						break;
					}
				}
			}
		}
	}
	
    protected void setPermissionMap(String path, HashMap<String, String> map) {
    	try {
			XSSFWorkbook xwb = new XSSFWorkbook(path);
			XSSFSheet sheet = xwb.getSheetAt(0);
			XSSFRow row;
			for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
				row = sheet.getRow(i);
				StringBuilder sb = new StringBuilder();
				if (row != null) {
					int j = 1;
					while (row.getCell(j) != null && !row.getCell(j).equals("")) {
						if (row.getCell(j).toString().contains("android")) {
							sb.append("&");
							sb.append(row.getCell(j).toString());
							j++;
						} else {
							break;
						}
					}
				}
				map.put(row.getCell(0).toString().split("[(]")[0], sb.substring(1));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void checkPermission(DedexerPlus ddxp) {
		dp = ddxp;
		if (cSet.size() > 0) {
			Iterator it = cSet.iterator();
        	while (it.hasNext()) {
        		String s = ((String )it.next());
        		if (s.contains("@")) {
            		String[] sa = s.split("@");
            		ddxp.getRegValueToCheck(sa[0], Long.parseLong(sa[1]), new int[]{Integer.parseInt(sa[2])}, sa[3], sa[4], 0, this);
        		}
        	}
		}
	}
}
